package com.huaxin.hxmodulesystem.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.huaxin.hxjwt.config.JwtUtils;
import com.huaxin.hxjwt.entity.JwtModel;
import com.huaxin.hxmodulesystem.common.PasswordUtil;
import com.huaxin.hxmodulesystem.dto.ResponseCode;
import com.huaxin.hxmodulesystem.dto.ResponseResult;
import com.huaxin.hxmodulesystem.dto.request.*;
import com.huaxin.hxmodulesystem.dto.response.ElectricianArchivesLoginRespDTO;
import com.huaxin.hxmodulesystem.mapper.ElectricianArchivesMapper;
import com.huaxin.hxmodulesystem.mapping.ElectricianArchivesMapping;
import com.huaxin.hxmodulesystem.models.ElectricianArchives;
import com.huaxin.hxmodulesystem.models.enums.AuditStatus;
import com.huaxin.hxmodulesystem.models.enums.BizType;
import com.huaxin.hxmodulesystem.service.ElectricianArchiveAuditRecordService;
import com.huaxin.hxmodulesystem.service.ElectricianArchivesService;
import com.huaxin.hxmodulesystem.service.SmsSendTaskService;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.cache.CacheManager;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Map;

@Service
@RequiredArgsConstructor
public class ElectricianArchivesServiceImpl extends ServiceImpl<ElectricianArchivesMapper, ElectricianArchives> implements ElectricianArchivesService {
    private final ApplicationContext applicationContext;
    private final ElectricianArchivesMapping electricianArchivesMapping;
    private final CacheManager cacheManager;
    private final ElectricianArchiveAuditRecordService electricianArchiveAuditRecordService;
    private final SmsSendTaskService smsSendTaskService;


    /**
     * 添加电工档案
     *
     * @param in
     * @return
     */
    @Override
    public ResponseResult<ElectricianArchives> addElectricianArchives(AddElectricianArchivesReqDTO in) {
        if (in == null) {
            return ResponseResult.parameterError(null, "参数错误");
        }
        if (StringUtils.isBlank(in.getRealName())) {
            return ResponseResult.parameterError(null, "真实姓名不能为空");
        }
        if (StringUtils.isBlank(in.getPhone())) {
            return ResponseResult.parameterError(null, "手机号不能为空");
        }
        if (StringUtils.isBlank(in.getPassword())) {
            return ResponseResult.parameterError(null, "密码不能为空");
        }
        if (StringUtils.isBlank(in.getCertificateNo())) {
            return ResponseResult.parameterError(null, "作业证书编号不能为空");
        }
        if (StringUtils.isBlank(in.getCertificatePicture())) {
            return ResponseResult.parameterError(null, "作业证书图片不能为空");
        }
        if (StringUtils.isBlank(in.getIdCardNumber())) {
            return ResponseResult.parameterError(null, "身份证编号不能为空");
        }
        if (StringUtils.isBlank(in.getIdPhotoFront())) {
            return ResponseResult.parameterError(null, "身份证正面图片不能为空");
        }
        if (StringUtils.isBlank(in.getIdPhotoReverse())) {
            return ResponseResult.parameterError(null, "身份证反面图片不能为空");
        }
        ElectricianArchives entity = electricianArchivesMapping.toEntity(in);
        entity.setPassword(PasswordUtil.hashPassword(entity.getPassword()));
        entity.setAuditStatus(AuditStatus.PENDING.getValue());
        if (this.save(entity)) {
            ElectricianArchives newEntity = this.getById(entity.getId());
            // 2. 获取自增 ID
            Integer autoId = newEntity.getAutoId();
            // 3. 生成工号
            String workNumber = String.format("%06d", autoId);
            newEntity.setWorkNumber(workNumber);
            this.updateById(newEntity);
            return ResponseResult.ok(newEntity);
        } else {
            return ResponseResult.failure(ResponseCode.INTERNAL_ERROR, "添加失败，请稍后再试！", null);
        }
    }

    /**
     * 修改电工档案
     *
     * @param in
     * @return
     */
    @Override
    public ResponseResult<String> updateElectricianArchives(UpdateElectricianArchivesReqDTO in) {
        if (in == null) {
            return ResponseResult.parameterError(null, "参数错误");
        }
        if (StringUtils.isBlank(in.getId())) {
            return ResponseResult.parameterError(null, "ID不能为空");
        }
        if (StringUtils.isBlank(in.getPhone())) {
            return ResponseResult.parameterError(null, "手机号不能为空");
        }
        if (StringUtils.isBlank(in.getCertificateNo())) {
            return ResponseResult.parameterError(null, "作业证书编号不能为空");
        }
        if (StringUtils.isBlank(in.getCertificatePicture())) {
            return ResponseResult.parameterError(null, "作业证书图片不能为空");
        }
        if (StringUtils.isBlank(in.getIdCardNumber())) {
            return ResponseResult.parameterError(null, "身份证编号不能为空");
        }
        if (StringUtils.isBlank(in.getIdPhotoFront())) {
            return ResponseResult.parameterError(null, "身份证正面图片不能为空");
        }
        if (StringUtils.isBlank(in.getIdPhotoReverse())) {
            return ResponseResult.parameterError(null, "身份证反面图片不能为空");
        }
        ElectricianArchives entity = this.getById(in.getId());
        electricianArchivesMapping.updateEntity(in, entity);
        entity.setAuditStatus(AuditStatus.PENDING.getValue());
        if (this.updateById(entity)) {
            return ResponseResult.ok("修改电工成功！");
        } else {
            return ResponseResult.failure(ResponseCode.INTERNAL_ERROR, "修改失败，请稍后再试！", null);
        }
    }


    /**
     * 删除电工档案
     *
     * @param id
     * @return
     */
    @Override
    public ResponseResult<String> deleteElectricianArchives(String id) {
        if (StringUtils.isBlank(id)) {
            return ResponseResult.parameterError(null, "ID不能为空");
        }
        ElectricianArchives electricianArchives = this.baseMapper.selectById(id);
        if (electricianArchives == null) {
            return ResponseResult.failure(ResponseCode.INTERNAL_ERROR, "电工不存在", null);
        }
        if (applicationContext.getBean(ElectricianArchivesService.class).removeById(id)) {
            return ResponseResult.ok("删除电工成功！");
        } else {
            return ResponseResult.failure(ResponseCode.INTERNAL_ERROR, "删除失败，请稍后再试！", null);
        }
    }

    /**
     * 获取电工档案列表
     *
     * @param pageNum     页码
     * @param pageSize    每页数量
     * @param workNumber  工号
     * @param realName    真实姓名
     * @param phone       手机号码
     * @param status      状态：0-正常；1-禁用
     * @param auditStatus 审核状态：0-待审核；1-审核通过；2-审核未通过
     * @return
     */
    @Override
    public ResponseResult<Page<ElectricianArchives>> getElectricianArchivesList(Integer pageNum, Integer pageSize, String workNumber, String realName, String phone, Integer status, Integer auditStatus) {
        Page<ElectricianArchives> page = new Page<>(pageNum, pageSize);
        QueryWrapper<ElectricianArchives> wrapper = new QueryWrapper<>();
        if (StringUtils.isNotBlank(workNumber)) {
            wrapper.like("work_number", workNumber);
        }
        if (StringUtils.isNotBlank(realName)) {
            wrapper.like("real_name", realName);
        }
        if (StringUtils.isNotBlank(phone)) {
            wrapper.like("phone", phone);
        }
        if (status != null && status > -1) {
            wrapper.eq("status", status);
        }
        if (auditStatus != null && auditStatus >= 0) {
            wrapper.eq("audit_status", auditStatus);
        }
        return ResponseResult.ok(this.baseMapper.selectPage(page, wrapper));
    }

    /**
     * 获取电工档案详情
     *
     * @param id
     * @return
     */
    @Override
    public ResponseResult<ElectricianArchives> getElectricianArchivesDetail(String id) {
        if (StringUtils.isBlank(id)) {
            return ResponseResult.parameterError(null, "ID不能为空");
        }
        return ResponseResult.ok(this.baseMapper.selectById(id));
    }

    //电工登录
    @Override
    public ResponseResult<ElectricianArchivesLoginRespDTO> electricianLogin(ElectricianLoginReqDTO in) {
        if (StringUtils.isBlank(in.getUserName())) {
            return ResponseResult.parameterError(null, "登录名不能为空！");
        }
        if (StringUtils.isBlank(in.getPassword())) {
            return ResponseResult.parameterError(null, "密码不能为空！");
        }
        QueryWrapper<ElectricianArchives> wrapper = new QueryWrapper<>();
        wrapper.and(w -> w.eq("work_number", in.getUserName()).or().eq("phone", in.getUserName()));
        ElectricianArchives user = this.baseMapper.selectOne(wrapper);
        if (user != null) {
            if (PasswordUtil.verifyPassword(in.getPassword(), user.getPassword())) {
                // 登录成功，生成 JWT Token
                JwtModel jwtModel = new JwtModel();
                jwtModel.setUserId(user.getId());
                String token = JwtUtils.generateToken(jwtModel);
                ElectricianArchivesLoginRespDTO userLoginRespDTO = new ElectricianArchivesLoginRespDTO();
                userLoginRespDTO.setToken(token);
                userLoginRespDTO.setElectricianArchives(user);
                return ResponseResult.ok(userLoginRespDTO);
            } else {
                return ResponseResult.failure(ResponseCode.INTERNAL_ERROR, "密码错误！", null);
            }
        }
        return ResponseResult.failure(ResponseCode.INTERNAL_ERROR, "用户不存在", null);
    }

    /**
     * 审核电工档案
     *
     * @param in
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)  // 重要：保证更新和记录在同一个事务中
    public ResponseResult<Boolean> audit(AuditElectricianReqDTO in) {
        // 1. 查询电工档案
        ElectricianArchives electricianArchive = this.baseMapper.selectById(in.getElectricianArchiveId());
        if (electricianArchive == null) {
            return ResponseResult.failure(ResponseCode.INTERNAL_ERROR, "电工档案不存在", null);
        }

        // 2. 校验当前状态（只能审核“待审核”状态的档案）
        if (electricianArchive.getAuditStatus() != AuditStatus.PENDING.getValue()) {
            return ResponseResult.failure(ResponseCode.INTERNAL_ERROR, "该档案已审核，无法重复操作", null);
        }

        // 3. 更新档案状态
        electricianArchive.setAuditStatus(in.getAuditStatus().getValue());
        this.updateById(electricianArchive);

        // 4. 添加审核记录
        AddElectricianArchiveAuditRecordReqDTO addElectricianArchiveAuditRecordReqDTO = AddElectricianArchiveAuditRecordReqDTO.builder()
                .electricianArchiveId(in.getElectricianArchiveId())
                .auditStatus(in.getAuditStatus())
                .comment(in.getComment())
                .build();
        electricianArchiveAuditRecordService.addElectricianArchiveAuditRecord(addElectricianArchiveAuditRecordReqDTO);

        // 5. 可选：发送短信通知
        CreateSmsTaskReqDTO smsSendTaskDTO = CreateSmsTaskReqDTO.builder()
                .bizId(in.getElectricianArchiveId())
                .bizType(BizType.ELECTRICIAN_AUDIT)
                .phone(electricianArchive.getPhone())
                .maxRetry(3)
                .build();
        if (in.getAuditStatus() == AuditStatus.APPROVED) {
            smsSendTaskDTO.setTemplateCode("SMS_XXXXXX");
            smsSendTaskDTO.setTemplateParams(Map.of("name", electricianArchive.getRealName()));
        } else if (in.getAuditStatus() == AuditStatus.REJECTED) {
            smsSendTaskDTO.setTemplateCode("SMS_XXXXXX");
            smsSendTaskDTO.setTemplateParams(Map.of("name", electricianArchive.getRealName(), "reason", in.getComment()));
        }
        smsSendTaskService.createSmsTask(smsSendTaskDTO);

        return ResponseResult.ok(true);
    }


}
